﻿using System;
using System.Collections.Generic;
using System.Data.EntityClient;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Transactions;
using System.Xml;

using Microsoft.Data.Extensions;
using PMP.EF.Local;
using PMP.Service.DTO;
using PMP.Service.Utility;

namespace PMP.Service.Implement
{
    public class DbConfigService
    {

        public int Timer { get; set; }
        public string UserName { get; set; }
        public string Password { get; set; }
        public string Smtp { get; set; }
        public DbConfigService()
        {

        }

        protected static string appConfigPath;

        public string AppConfigPath 
        {
            get { return appConfigPath; }
        }
        public DbConfigService(string zaaaa)
        {
            appConfigPath = zaaaa;
        }

        private XmlDocument ReadDbConfig()
        {
            XmlDocument dbConfigXml = new XmlDocument();


            if (string.IsNullOrEmpty(appConfigPath))
            {
                dbConfigXml.Load(System.Web.HttpContext.Current.Server.MapPath("~/AppConfig.xml"));
            }
            else
            {
                //D:\Projects\pmp1\main\program\trunk\PMP.ConsoleService\bin\Debug
                dbConfigXml.Load(appConfigPath);
            }

            return dbConfigXml;
        }

        public WinServiceDTO GetWindowsServiceConfig()
        {
            WinServiceDTO e = new WinServiceDTO();
            XmlDocument dbConfigXml = ReadDbConfig();
            XmlNodeList listXml = dbConfigXml.GetElementsByTagName("WindowsServiceConfig")[0].ChildNodes;
            string name, value;
            foreach (XmlNode node in listXml)
            {
                name = node.Name;
                value = node.InnerXml;
                switch (name)
                {
                    case WinServiceConfigName.Smtp: e.Smtp = value; break;
                    case WinServiceConfigName.HttpPath: e.HttpPath = value; break;
                }
            }
            return e;
        }

        public List<string> GetLocalDBForWinService()
        {
            List<string> list = new List<string>();
            XmlDocument dbConfigXml = ReadDbConfig();
            XmlNodeList localListXml = dbConfigXml.GetElementsByTagName("Local")[0].ChildNodes;
            string strConnection;
            foreach (XmlNode node in localListXml)
            {
                list.Add(node.Name);
            }

            return list;
        }

        public string GetGlobalConnectionString()
        {
            XmlDocument dbConfigXml = ReadDbConfig();
            XmlNodeList globalListXml = dbConfigXml.GetElementsByTagName("Global")[0].ChildNodes;
            string globalConnectionString = CreateConnectionString(globalListXml);
            globalConnectionString = BuildEntityConnectionString(globalConnectionString, DbType.Global);
            return globalConnectionString;
        }

        public string GetLocalConnectionString(string countryCode)
        {
            XmlDocument dbConfigXml = ReadDbConfig();
            XmlNodeList localListXml = dbConfigXml.GetElementsByTagName(countryCode)[0].ChildNodes;
            string localConnectionString = CreateConnectionString(localListXml);
            localConnectionString = BuildEntityConnectionString(localConnectionString, DbType.Local);
            return localConnectionString;
        }

        public string CreateConnectionString(XmlNodeList listXml)
        {
            StringBuilder connectionString = new StringBuilder("Data Source={0}; Initial Catalog={1}; Integrated Security=SSPI; MultipleActiveResultSets=True; Connection Timeout=30;");
            string name, value;

            foreach (XmlNode node in listXml)
            {
                name = node.Name;
                value = node.InnerXml;
                switch (name)
                {
                    case AppConfigName.DB_InstanceName: connectionString.Replace("{0}", value); break;
                    case AppConfigName.DB_DatabaseName: connectionString.Replace("{1}", value); break;
                }
            }

            return connectionString.ToString();
        }

        private string BuildEntityConnectionString(string connectionString, string dbType)
        {
            string providerName = "System.Data.SqlClient";
            EntityConnectionStringBuilder entityBuilder = new EntityConnectionStringBuilder();
            entityBuilder.Provider = providerName;
            entityBuilder.ProviderConnectionString = connectionString;

            // Set the Metadata location.
            if (dbType.Equals(DbType.Local))
            {
                entityBuilder.Metadata = @"res://*/Local.LocalPMP.csdl|
                            res://*/Local.LocalPMP.ssdl|
                            res://*/Local.LocalPMP.msl";
            }
            else if (dbType.Equals(DbType.Global))
            {
                entityBuilder.Metadata = @"res://*/Global.GlobalPMP.csdl|
                            res://*/Global.GlobalPMP.ssdl|
                            res://*/Global.GlobalPMP.msl";
            }

            return entityBuilder.ToString();
        }

        #region Get Application Configuration from AppConfig.xml
        private static string copyRightYear;
        public static string CopyRightYear
        {
            get
            {
                if (string.IsNullOrEmpty(copyRightYear))
                {
                    DbConfigService configService = new DbConfigService();
                    XmlDocument appConfigXml = configService.ReadDbConfig();
                    XmlNode copyRightNode = appConfigXml.GetElementsByTagName(AppConfigName.CopyRightYear)[0];

                    copyRightYear = copyRightNode.InnerXml;
                }

                return copyRightYear;
            }
        }

        private static string systemEmail;
        public static string SystemEmail
        {
            get
            {
                DbConfigService configService;
                if (!string.IsNullOrEmpty(appConfigPath))
                {
                    configService = new DbConfigService(appConfigPath);
                }
                else 
                {
                    configService = new DbConfigService();
                }
                    
                if (string.IsNullOrEmpty(systemEmail))
                    {
                        
                        XmlDocument appConfigXml = configService.ReadDbConfig();
                        XmlNodeList systemEmailNodes = appConfigXml.GetElementsByTagName(AppConfigName.SystemEmail)[0].ChildNodes;

                        foreach (XmlNode node in systemEmailNodes)
                        {
                            switch (node.Name)
                            {
                                case AppConfigName.Email: systemEmail = node.InnerXml; break;
                                case AppConfigName.DisplayName: systemEmailName = node.InnerXml; break;
                            }
                        }
                    }
             
                return systemEmail;
            }
        }

        private static string systemEmailName;
        public static string SystemEmailName
        {
            get
            {
                DbConfigService configService;
                if (!string.IsNullOrEmpty(appConfigPath))
                {
                    configService = new DbConfigService(appConfigPath);
                }
                else
                {
                    configService = new DbConfigService();
                }

                if (string.IsNullOrEmpty(systemEmailName))
                {
                    XmlDocument appConfigXml = configService.ReadDbConfig();
                    XmlNodeList systemEmailNodes = appConfigXml.GetElementsByTagName(AppConfigName.SystemEmail)[0].ChildNodes;

                    foreach (XmlNode node in systemEmailNodes)
                    {
                        switch (node.Name)
                        {
                            case AppConfigName.Email: systemEmail = node.InnerXml; break;
                            case AppConfigName.DisplayName: systemEmailName = node.InnerXml; break;
                        }
                    }
                }

                return systemEmailName;
            }
        }


        #endregion
    }
}
